package com.yuezhu.versionup;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 下载总管理类
 * 
 * @author zuo
 */
public class DownloadManager {

	private static DownloadManager instance;

	private static ThreadPoolManager threadPool;

	private Context mContext;

	// 线程池最大线程数
	private static int threadPoolCount = 8;
	// 默认文件拆分线程数
	private static int threadCount = 5;

	private DownloadManager(Context context) {
		this.mContext = context;
	}

	/**
	 * 获取单例
	 * 
	 * @param context
	 * @return
	 */
	public static DownloadManager getInstance(Context context) {
		if (instance == null) {
			instance = new DownloadManager(context);
			// 启动线程池
			threadPool = new ThreadPoolManager(threadPoolCount);
			threadPool.start();
		}
		return instance;
	}

	/**
	 * 添加下载任务
	 * 
	 * @param downUrl
	 * @param destPath
	 * @param handler
	 */
	public void addDownTask(String taskId, String downUrl, String destPath,
							Handler handler) {
		new Thread(new AddTaskThread(taskId, downUrl, destPath, handler))
				.start();
	}

	/**
	 * 暂停下载
	 * 
	 * @param downUrl
	 */
	public void pauseTask(String taskId, String downUrl, Handler handler) {
		threadPool.pauseTask(taskId);
		// 移除队列
		TaskQueue.getInst().remove(taskId);
		// 通知
		if (null != handler) {
			Message message = Message.obtain();
			message.what = DownloadState.PAUSE;
			message.obj = taskId;
			handler.sendMessage(message);
		}
	}

	/**
	 * 继续下载任务
	 * 
	 * @param downUrl
	 * @param destPath
	 * @param handler
	 */
	public void continueTask(String taskId, String downUrl, String destPath,
							 Handler handler) {
		addDownTask(taskId, downUrl, destPath, handler);
	}

	/**
	 * 移除下载任务
	 * 
	 * @param downUrl
	 * @param handler
	 */
	public void removeTask(String taskId, String downUrl, Handler handler) {
		if (null != downUrl) {
			// 先把任务暂停,然后删除数据库相关信息
			pauseTask(taskId, downUrl, null);
			SQLiteDownDatabase.getInstance(mContext).delete(taskId);
			if (null != handler) {
				Message message = Message.obtain();
				message.what = DownloadState.REMOVE;
				message.obj = taskId;
				handler.sendMessage(message);
			}
		}
	}

	/**
	 * 重新添加下载任务
	 * 
	 * @param downUrl
	 * @param destPath
	 * @param handler
	 */
	public void reAddDownTask(String taskId, String downUrl, String destPath,
							  Handler handler) {
		// 先删除
		removeTask(taskId, downUrl, null);
		// 再添加
		addDownTask(taskId, downUrl, destPath, handler);
	}

	// =========================以下方法内部使用逻辑====================================================//
	private class AddTaskThread implements Runnable {
		Handler handler;
		String taskId;
		String downUrl;
		String destPath;

		public AddTaskThread(String taskId, String downUrl, String destPath,
							 Handler handler) {
			this.taskId = taskId;
			this.downUrl = downUrl;
			this.destPath = destPath;
			this.handler = handler;
		}

		@Override
		public void run() {
			// 分析
			System.out.println(downUrl + " liu game download to " + destPath);
			DownloadInfo downInfo = getDownloaderInfors(taskId, downUrl,
					destPath);
			downInfo.setMyContext(mContext);
			downInfo.setMsgHandler(handler);
			// 加入队列
			TaskQueue.getInst().addMessage(downInfo);

			System.out.println("liu game put into taskqueue");
		}

	}

	/**
	 * 首先进行判断是否是第一次下载，如果是第一次就要进行初始化，并将下载信息保存到数据库中
	 * 如果不是第一次下载，那就要从数据库中读出之前下载的信息（起始位置，结束为止，文件大小等），并将下载信息返回
	 * 
	 * @param downUrl
	 * @param destPath
	 * @return DownloadInfo
	 */
	private DownloadInfo getDownloaderInfors(String taskId, String downUrl,
											 String destPath) {
		DownloadInfo loadInfo = new DownloadInfo();

		int fileSize = 0;// 文件总大小
		List<DownloadInfoTask> childDownInfos;
		int compeleteSize = 0;
		if (isFirst(taskId)) {
			Log.v("TAG", "isFirst");
			fileSize = init(downUrl, destPath);

			int range = fileSize / threadCount;
			childDownInfos = new ArrayList<DownloadInfoTask>();
			for (int i = 0; i < threadCount - 1; i++) {
				DownloadInfoTask info = new DownloadInfoTask(i, i * range,
						(i + 1) * range - 1, 0, taskId, downUrl, destPath);
				childDownInfos.add(info);
			}
			DownloadInfoTask info = new DownloadInfoTask(threadCount - 1,
					(threadCount - 1) * range, fileSize - 1, 0, taskId,
					downUrl, destPath);
			childDownInfos.add(info);
			// 保存infos中的数据到数据库
			SQLiteDownDatabase.getInstance(mContext).saveInfos(childDownInfos);

		} else {
			// 得到数据库中已有的taskId的下载器的具体信息
			childDownInfos = SQLiteDownDatabase.getInstance(mContext).getInfos(
					taskId);
			Log.v("TAG", "not isFirst size=" + childDownInfos.size());
			for (DownloadInfoTask info : childDownInfos) {
				compeleteSize += info.getCompeleteSize();
				fileSize += info.getEndPos() - info.getStartPos() + 1;
			}
		}

		loadInfo.setFileSize(fileSize);
		loadInfo.setCompeleteSize(compeleteSize);
		loadInfo.setDownUrl(downUrl);
		loadInfo.setTaskId(taskId);

		loadInfo.setChildDownInfos(childDownInfos);

		return loadInfo;
	}

	/**
	 * 判断是否是第一次 下载
	 */
	private boolean isFirst(String taskId) {
		return SQLiteDownDatabase.getInstance(mContext).isHasInfors(taskId);
	}

	/**
	 * 获取网络文件大小，并创建本地文件
	 * 
	 * @param downUrl
	 * @param destPath
	 * @return int
	 */
	private int init(String downUrl, String destPath) {
		int fileSize = 0;
		try {
			URL url = new URL(downUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.setConnectTimeout(5000);
			connection.setRequestMethod("GET");
			fileSize = connection.getContentLength();

			File file = new File(destPath);
			if (!file.exists()) {
				file.createNewFile();
			}
			// 本地访问文件
			RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
			accessFile.setLength(fileSize);
			accessFile.close();
			connection.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return fileSize;
	}
}
